package com.it.schoolbookshop_back.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类，用于生成和解析JWT令牌
 */
public class JwtUtil {
    // 密钥
    private static final String SECRET = "schoolbookshop_secret_key";
    // 签发者
    private static final String ISSUER = "schoolbookshop";
    // 默认过期时间（24小时）
    private static final long EXPIRE_TIME = 24 * 60 * 60 * 1000;

    /**
     * 生成JWT令牌
     * @param userId 用户ID
     * @param username 用户名
     * @return JWT令牌
     */
    public static String generateToken(String userId, String username) {
        return generateToken(userId, username, EXPIRE_TIME);
    }

    /**
     * 生成JWT令牌（包含角色信息）
     * @param userId 用户ID
     * @param username 用户名
     * @param role 用户角色
     * @return JWT令牌
     */
    public static String generateToken(String userId, String username, String role) {
        return generateToken(userId, username, role, EXPIRE_TIME);
    }

    /**
     * 生成JWT令牌（指定过期时间）
     * @param userId 用户ID
     * @param username 用户名
     * @param expireTime 过期时间（毫秒）
     * @return JWT令牌
     */
    public static String generateToken(String userId, String username, long expireTime) {
        try {
            // 设置过期时间
            Date expireDate = new Date(System.currentTimeMillis() + expireTime);
            
            // 头部信息
            Map<String, Object> headerClaims = new HashMap<>();
            headerClaims.put("alg", "HS256");
            headerClaims.put("typ", "JWT");
            
            // 使用HMAC256算法创建JWT
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            
            return JWT.create()
                    .withHeader(headerClaims)
                    .withIssuer(ISSUER)
                    .withIssuedAt(new Date())
                    .withExpiresAt(expireDate)
                    .withClaim("userId", userId)
                    .withClaim("username", username)
                    .sign(algorithm);
        } catch (JWTCreationException exception) {
            // 创建JWT失败
            return null;
        }
    }
    
    /**
     * 生成JWT令牌（指定过期时间和角色）
     * @param userId 用户ID
     * @param username 用户名
     * @param role 用户角色
     * @param expireTime 过期时间（毫秒）
     * @return JWT令牌
     */
    public static String generateToken(String userId, String username, String role, long expireTime) {
        try {
            // 设置过期时间
            Date expireDate = new Date(System.currentTimeMillis() + expireTime);
            
            // 头部信息
            Map<String, Object> headerClaims = new HashMap<>();
            headerClaims.put("alg", "HS256");
            headerClaims.put("typ", "JWT");
            
            // 使用HMAC256算法创建JWT
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            
            return JWT.create()
                    .withHeader(headerClaims)
                    .withIssuer(ISSUER)
                    .withIssuedAt(new Date())
                    .withExpiresAt(expireDate)
                    .withClaim("userId", userId)
                    .withClaim("username", username)
                    .withClaim("role", role)
                    .sign(algorithm);
        } catch (JWTCreationException exception) {
            // 创建JWT失败
            return null;
        }
    }

    /**
     * 验证JWT令牌
     * @param token JWT令牌
     * @return 验证结果，成功返回true，失败返回false
     */
    public static boolean verifyToken(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build();
            verifier.verify(token);
            return true;
        } catch (JWTVerificationException exception) {
            // 验证失败
            return false;
        }
    }

    /**
     * 解析JWT令牌
     * @param token JWT令牌
     * @return 解析后的JWT对象，如果解析失败则返回null
     */
    public static DecodedJWT parseToken(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build();
            return verifier.verify(token);
        } catch (JWTVerificationException exception) {
            // 验证失败
            return null;
        }
    }

    /**
     * 从JWT令牌中获取用户ID
     * @param token JWT令牌
     * @return 用户ID，如果解析失败则返回null
     */
    public static String getUserId(String token) {
        DecodedJWT jwt = parseToken(token);
        return jwt != null ? jwt.getClaim("userId").asString() : null;
    }

    /**
     * 从JWT令牌中获取用户名
     * @param token JWT令牌
     * @return 用户名，如果解析失败则返回null
     */
    public static String getUsername(String token) {
        DecodedJWT jwt = parseToken(token);
        return jwt != null ? jwt.getClaim("username").asString() : null;
    }

    /**
     * 检查令牌是否已过期
     * @param token JWT令牌
     * @return 是否已过期，过期返回true，未过期返回false
     */
    public static boolean isTokenExpired(String token) {
        DecodedJWT jwt = parseToken(token);
        if (jwt == null) {
            return true;
        }
        Date expiresAt = jwt.getExpiresAt();
        return expiresAt != null && expiresAt.before(new Date());
    }

    /**
     * 从JWT令牌中获取用户角色
     * @param token JWT令牌
     * @return 用户角色，如果解析失败则返回null
     */
    public static String getRole(String token) {
        DecodedJWT jwt = parseToken(token);
        return jwt != null ? jwt.getClaim("role").asString() : null;
    }
}
